import { AfterViewChecked, Input, OnInit, QueryList, ViewChildren } from '@angular/core';
import { FormComponent } from '../../common/form/form.component';
import { BaseView } from './base-view';


/**
 * 表单视图类主要功能为提供表单校验
 */
export class FormView<U, B, S> extends BaseView<U, B, S> implements AfterViewChecked, OnInit {

  @ViewChildren(FormComponent) formComponentList: QueryList<FormComponent<U, B, S>>;
  @Input() formData: any = {};
  /** 当前表单校验是否有异常 */
  formMainValidateError: boolean;
  private _ngAfterViewChecked = false;
  private _ngOnInit = false;

  constructor() {
    super();
    this.ngZone.runOutsideAngular(() => {
      setTimeout(() => {
        if (!this._ngOnInit) {
          this.loggerService.error(new Error('"super.ngOnInit()" Not Implemented ---> ' + this.constructor.name));
        }
        if (!this._ngAfterViewChecked) {
          this.loggerService.error(new Error('"super.ngAfterViewChecked()" Not Implemented ---> ' + this.constructor.name));
        }
      }, 3000);
    });
  }

  ngOnInit(): void {
    this._ngOnInit = true;
    if (!this.formData) {
      this.loggerService.error(new Error('formData is empty ---> ' + this.constructor.name));
    }

    // 是否点击过提交按钮
    this.formData._submitted = false;
    // 数据是否在发送中
    this.formData._submitting = false;
  }

  ngAfterViewChecked(): void {
    this._ngAfterViewChecked = true;
    if (this.formData && this.formComponentList && !this.formData._formComponentList) {
      this.formData._formComponentList = this.formComponentList;
    }
  }

  submitProxy(params?: any) {
    if (!this.formData._submitted) {
      this.formData._submitted = true;

      Object.keys(this.formData).forEach((key) => {
        if (key.startsWith('subForm')) {
          this.formData[key]._submitted = true;
        }
      });

      // 跨过一次脏值检查来保证表单校验状态能够实时反应到isValid属性上
      setTimeout(() => {
        this.submitProxy(params);
      }, 300);
      return;
    }

    let inValidKey: string | number;
    if (this.formData._formComponentList) {
      this.formComponentList.filter((f) => {
        if (params && Array.isArray(params._validWhiteList)) {
          return f.bzName && params._validWhiteList.includes('$' + f.bzName);
        }
        return true;
      }).forEach((f, i) => {
        if (!f.isValid && inValidKey === undefined) {
          inValidKey = 'main';
          this.postInvalid(inValidKey, i);
        }
      });
    }

    const keys = Object.keys(this.formData).filter((k) => {
      if (!k.startsWith('subForm')) {
        return false;
      }
      if (params && Array.isArray(params._validWhiteList)) {
        return params._validWhiteList.includes(k);
      }
      return true;
    });

    keys.forEach((key) => {
      const formComponentList = this.formData[key]._formComponentList;
      if (formComponentList) {
        formComponentList.forEach((f, i) => {
          if (!f.isValid && inValidKey === undefined) {
            inValidKey = key;
            this.postInvalid(inValidKey, i);
          }
        });
      }
    });

    if (inValidKey !== undefined) {
      this.formMainValidateError = true;
    } else {
      this.formMainValidateError = false;
      const formData = this.serializeData(this.formData);

      this.submit(formData, params);
    }
  }

  /** 子类需要重写父类的方法 某个表单校验失败之后的回调 */
  protected postInvalid(key: string, index: number) {
  }

  /** 子类需要重写父类的方法 校验成功之后的回调 */
  protected submit(formData: any, params?: any) {
  }

}
